package multi_thread.advanced;

/**
 * @author Cheng Jun
 * Description: 线程变量，每个线程都有个副本，以 ThreadLocalMap的形式保存键值对，key为线程变量 ThreadLocal对象，value为 副本值
 * ThreadLocal 不能在父子线程中传递，InheritableThreadLocal 可以
 * @version 1.0
 * @date 2020/3/4 20:29
 * @see InheritableThreadLocalExample
 */
public class ThreadLocalExample {
    private final static ThreadLocal<Integer> data = new ThreadLocal<>();

    public static void main(String[] args) throws Exception {

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "number 初始值：" + data.get());
            try {
                Thread.sleep(2000);
                System.out.println("其它线程修改data，本线程——" + Thread.currentThread().getName() +
                        "没有影响 number：" + data.get());
                // 设置线程变量
                data.set(100);
                System.out.println(Thread.currentThread().getName() + "number 修改后：" + data.get());
                System.out.println(Thread.currentThread().getName() + " data.remove(); 有效防止内存泄露");
                data.remove();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "线程A ").start();

        Thread.sleep(1000);

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "number 初始值：" + data.get());
            data.set(200);
            System.out.println(Thread.currentThread().getName() + "number 修改后：" + data.get());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("其它线程修改data，本线程——" + Thread.currentThread().getName() +
                    "没有影响 number：" + data.get());
            System.out.println(Thread.currentThread().getName() + " data.remove(); 有效防止内存泄露");
            data.remove();
        }, "线程B ").start();
    }
}
